package com.bjpowernode.boss.web.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bjpowernode.boss.common.cilent.RedisClient;
import com.bjpowernode.boss.common.constants.KeyConstants;
import com.bjpowernode.boss.common.enums.AjaxCode;
import com.bjpowernode.boss.common.enums.Status;
import com.bjpowernode.boss.common.error.BossException;
import com.bjpowernode.boss.common.utils.NoUtil;
import com.bjpowernode.boss.db.domain.PayProduct;
import com.bjpowernode.boss.db.mapper.PayProductMapper;
import com.bjpowernode.boss.web.service.PayProductService;
import com.bjpowernode.boss.web.models.form.ProductForm;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class PayProductServiceImpl implements PayProductService {
    @Resource
    RedisClient redisClient;
    @Resource
    private PayProductMapper payProductMapper;

    @Override
    public List<PayProduct> getAllProducts() {
        List<PayProduct> payProducts;
        try {
            String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
            if(StrUtil.isNotBlank(payProductJSON)){
                payProducts = JSONUtil.toList(payProductJSON, PayProduct.class);
            }else{
                synchronized (this) {
                    payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
                    if(StrUtil.isNotBlank(payProductJSON)){
                        payProducts = JSONUtil.toList(payProductJSON,PayProduct.class);
                    }else{
                        payProducts = payProductMapper.selectList(null);
                        if(!payProducts.isEmpty()){
                            redisClient.setValue(KeyConstants.PAY_PRODUCT_ALL,JSONUtil.toJsonStr(payProducts));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            payProducts = payProductMapper.selectList(null);
        }
        return payProducts;
    }

    @Override
    @Transactional
    public boolean addProduct(PayProduct productForm) {
        String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
        if(StrUtil.isNotBlank(payProductJSON)){
            List<PayProduct> list =  JSONUtil.toList(payProductJSON,PayProduct.class);
            for (PayProduct product : list) {
                if(product.getProductCode().equals(productForm.getProductCode())){
                    throw new BossException(AjaxCode.PAY_PRODUCT_CODE_DUPLICATE);
                }
                if(product.getProductName().equals(productForm.getProductName())){
                    throw new BossException(AjaxCode.PAY_PRODUCT_CODE_DUPLICATE);
                }
            }
        }
        QueryWrapper<PayProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_code",productForm.getProductCode());
        if(payProductMapper.selectOne(queryWrapper)!=null){
            throw new BossException(AjaxCode.PAY_PRODUCT_CODE_DUPLICATE);
        }
        queryWrapper.eq("product_name",productForm.getProductName());
        if(payProductMapper.selectOne(queryWrapper)!=null){
            throw new BossException(AjaxCode.PAY_PRODUCT_NAME_DUPLICATE);
        }

        if(StrUtil.isNotBlank(payProductJSON)){
            redisClient.deleteValue(KeyConstants.PAY_PRODUCT_ALL);
        }
        productForm.setId(NoUtil.getUUID());
        productForm.setStatus(Status.ENABLE.name());
        productForm.setEditTime(new Date());
        productForm.setRemark("创建支付产品");
        int number = payProductMapper.insert(productForm);
        return number>0;
    }

    @Override
    public boolean changeStatus(String id,String status) {
        String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
        if(StrUtil.isNotBlank(payProductJSON)){
            redisClient.deleteValue(KeyConstants.PAY_PRODUCT_ALL);
        }
        UpdateWrapper<PayProduct> updateWrapper=new UpdateWrapper<>();
        updateWrapper.set("status", status).eq("id",id);
        int number = payProductMapper.update(updateWrapper);
        return number>0;
    }

    @Override
    @Transactional
    public boolean editProduct(ProductForm productForm) {
        String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
        if(StrUtil.isNotBlank(payProductJSON)){
            List<ProductForm> list =  JSONUtil.toList(payProductJSON,ProductForm.class);
            int productCodeNumber = 0,productNameNumber=0;
            for (ProductForm product : list) {
                if(product.getProductCode().equals(productForm.getProductCode())){
                    productCodeNumber++;
                }
                if(product.getProductName().equals(productForm.getProductName())){
                    productNameNumber++;
                }
            }
            if(productCodeNumber>1){
                throw new BossException(AjaxCode.PAY_PRODUCT_CODE_DUPLICATE);
            }
            if(productNameNumber>1){
                throw new BossException(AjaxCode.PAY_PRODUCT_NAME_DUPLICATE);
            }
        }
        QueryWrapper<PayProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_code",productForm.getProductCode());
        if(payProductMapper.selectList(queryWrapper).size()>1){
            throw new BossException(AjaxCode.PAY_PRODUCT_CODE_DUPLICATE);
        }
        queryWrapper.eq("product_name",productForm.getProductName());
        if(payProductMapper.selectList(queryWrapper).size()>1){
            throw new BossException(AjaxCode.PAY_PRODUCT_NAME_DUPLICATE);
        }
        if(StrUtil.isNotBlank(payProductJSON)){
            redisClient.deleteValue(KeyConstants.PAY_PRODUCT_ALL);
        }
        UpdateWrapper<PayProduct> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("product_code",productForm.getProductCode()).set("product_name",productForm.getProductName()).eq("id",productForm.getId());
        int number = payProductMapper.update(updateWrapper);
        return number>0;
    }

    @Override
    public boolean singleDelete(String id) {
        String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
        if(StrUtil.isNotBlank(payProductJSON)){
            redisClient.deleteValue(KeyConstants.PAY_PRODUCT_ALL);
        }
        int number = payProductMapper.deleteById(id);
        return number>0;
    }

    @Override
    public boolean batchDelete(List<String> ids) {
        String payProductJSON = redisClient.getValue(KeyConstants.PAY_PRODUCT_ALL);
        if(StrUtil.isNotBlank(payProductJSON)){
            redisClient.deleteValue(KeyConstants.PAY_PRODUCT_ALL);
        }
        int number = payProductMapper.deleteBatchIds(ids);
        return number>0;
    }
}
